﻿using System;
using MarriageFertility.Actions;
using MarriageFertility.Helpers;
using MarriageFertility.Missions;
using MarriageFertility.Texts;
using StoryMode;
using TaleWorlds.CampaignSystem;
using TaleWorlds.CampaignSystem.Actions;
using TaleWorlds.CampaignSystem.Extensions;
using TaleWorlds.CampaignSystem.GameMenus;
using TaleWorlds.Localization;
using TaleWorlds.SaveSystem;

namespace MarriageFertility.Quests;

public class CompetitionQuest : StoryModeQuestBase
{
    [SaveableField(1)] private JournalLog _startLog;
    [SaveableField(2)] private Hero _competitor;
    [SaveableField(3)] private Hero _lover;
    public CompetitionQuest(string questId, Hero lover, Hero competitor, CampaignTime duration) : base(questId, lover, duration)
    {
        _competitor = competitor;
        _lover = lover;
        var startLog = GetStartLog(lover, competitor);
        _startLog = AddDiscreteLog(startLog, TalkLog, 0, 1);
        AddDialogs();
    }

    private TextObject GetStartLog(Hero lover, Hero competitor)
    {
        TextObject startLog = QuestText.CompetitionQuestDetail;
        startLog.SetCharacterProperties("Player", Hero.MainHero.CharacterObject);
        startLog.SetCharacterProperties("LovedOne", lover.CharacterObject);
        startLog.SetCharacterProperties("Rival", competitor.CharacterObject);
        return startLog;
    }

    private TextObject TalkLog => QuestText.CompetitorTaskTitle.SetTextVariable("heroName", _competitor.Name);


    protected override void RegisterEvents()
    {
    }

    protected override void HourlyTick()
    {
        if (_competitor != null && _lover != null)
        {
            if (_competitor.IsDead)
            {
                UpdateQuestTaskStage(_startLog, 1);
                Hero.MainHero.ForceMarry(_lover);
                CompleteQuestWithSuccess();
            }
            else if (_lover.IsDead)
            {
                CompleteQuestWithFail(QuestText.LoverDeathLog);
            }
        }
    }


    private TextObject TimeOutLog => QuestText.CompetitionQuestTimeOutLog;


    protected override void OnTimedOut()
    {
        try
        {
            _competitor.ForceNpcMarry(QuestGiver, false);
        }
        catch (Exception e)
        {
            Log.ErrorMessage(e.StackTrace);
        }
    }


    public override TextObject Title => QuestText.CompetitorQuestTitle;


    protected override void InitializeQuestOnGameLoad()
    {
        SetDialogs();
    }

    protected override void SetDialogs()
    {
        AddDialogs();
    }

    private void AddDialogs()
    {
        Campaign.Current.ConversationManager.AddDialogFlow(GetCompetitionDuelQuestDialog(), this);
    }

    private DialogFlow GetCompetitionDuelQuestDialog()
    {
        return DialogFlow.CreateDialogFlow("hero_main_options", 150)
            .BeginPlayerOptions()
            .PlayerSpecialOption(QuestText.ChallengeRivalDialog)
            .Condition(IsCompetitorHero)
            .NpcLine(QuestText.RivalAcceptsChallengeDialog)
            .Consequence(StartDuelWithCompetitor)
            .CloseDialog();
    }

    private bool IsCompetitorHero()
    {
        return Hero.OneToOneConversationHero != null && _competitor == Hero.OneToOneConversationHero;
    }

    private void StartDuelWithCompetitor()
    {
        Hero competitor = _competitor;
        Hero lover = _lover;
        if (competitor != null)
        {
            DuelManager.DuelFightResult = DuelManager.DuelFightResultEnum.None;
            DuelManager.DuelHero = competitor.CharacterObject;

            DuelManager.WinCallEvent = () => { ConfirmDuelVictory(competitor, lover); };

            DuelManager.LoseCallEvent = ConfirmDuelLose;

            TextObject duelMessage = QuestText.ChallengeDuel.SetTextVariable("HERO_NAME",
                    competitor.Name.ToString());
            DuelManager.DuelMenuTitle = duelMessage.ToString();
            DuelManager.DuelFightType = DuelManager.DuelFightTypeEnum.Single;
            GameMenu.SwitchToMenu(DuelManager.MdMenu);
        }
    }

    private void ConfirmDuelVictory(Hero competitor, Hero lover)
    {
        ChangeRelationAction.ApplyPlayerRelation(competitor, 20);
        ChangeRelationAction.ApplyPlayerRelation(lover, 50);
        ChangeRelationAction.ApplyRelationChangeBetweenHeroes(competitor, lover, -50);
        UpdateQuestTaskStage(_startLog, 1);
        Hero.MainHero.ForceMarry(lover);
        CompleteQuestWithSuccess();
    }

    private void ConfirmDuelLose()
    {
        ChangeRelationAction.ApplyPlayerRelation(_competitor, -50);
        ChangeRelationAction.ApplyPlayerRelation(_lover, -20);
        ChangeRelationAction.ApplyRelationChangeBetweenHeroes(_competitor, _lover, 50);
        _competitor.ForceNpcMarry(_lover, false);
        CompleteQuestWithFail(QuestText.DuelLose);
    }
}